package com.czk.buffer;

import org.junit.Test;

import java.nio.ByteBuffer;

/**
 * 一、缓冲区：在java nio中负责数据的存取，缓冲区就是数组，用于存储不同的数据
 * 根据数据类型的不同，提供相应类型的缓冲区
 * ByteBuffer
 * CharBuffer
 * ShortBuffer
 * IntBuffer
 * LongBuffer
 * FloatBuffer
 * DoubleBuffer
 * 通过allocate()方法获取缓冲区
 * 二、核心方法：
 * 1 put() 存入到缓冲区
 * 2 get() 获取缓冲区数据
 * 三、四个核心数据
 * 1 capacity :容量，缓冲区中最大存储数据的容量，一旦声明不能改变
 * 2 limit: 界限，表示缓冲区中可以操作数据的大小（limit后面的数据不能进行读写）
 * 3 position： 表示缓冲区中正在操作数据的位置 0《=mark<=position<=limy<=capacity
 * 4 mark :标记，记录当前position的位置,可以通过reset恢复到mark的位置
 * 四、直接缓冲区和非直接缓冲区
 * 1 非直接缓冲区：通过allocate()创建，缓冲区创建在jvm中
 * 2 直接缓冲区： allocateDirect()
 *
 * @Author:ChenZhangKun
 * @Date: 2021/1/8 22:34
 */
public class BufferTest {
    @Test
    public void test1() {
        // 创建字节缓冲区
        ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
        // 获取属性
        // 位置
        int position = byteBuffer.position();
        // 界限
        int limit = byteBuffer.limit();
        // 容量
        int capacity = byteBuffer.capacity();
        // 0
        System.out.println(position);
        // 1024
        System.out.println(limit);
        // 1024
        System.out.println(capacity);
        // 添加数据
        byteBuffer.put("陈彰坤".getBytes());
        // 位置position变成3
        System.out.println(byteBuffer.position());

        // 切换读取数据模式
        byteBuffer.flip();
        // 位置 0
        System.out.println(byteBuffer.position());
        // 界限 3
        System.out.println(byteBuffer.limit());

        // 读取字节数组
        byte[] bytes = new byte[byteBuffer.limit()];
        byteBuffer.get(bytes);
        System.out.println(new String(bytes));
        // 位置 3
        System.out.println(byteBuffer.position());
        System.out.println(byteBuffer.limit());
        // 可重复读 重新初始化position位置
        byteBuffer.rewind();
        System.out.println(byteBuffer.limit());
        System.out.println(byteBuffer.position());

        // 请客缓存区 此时指针回归原位，但是数据并没有被清理，属于被遗忘状态
        byteBuffer.clear();
        // 0
        System.out.println(byteBuffer.position());
        // 1024
        System.out.println(byteBuffer.limit());
    }

    /**
     * 测试mark标记
     */
    @Test
    public void test2() {
        ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
        byteBuffer.put("kdkd".getBytes());
        byteBuffer.flip();
        byte[] bytes = new byte[byteBuffer.limit()];
        byteBuffer.get(bytes, 0, 2);
        System.out.println(new String(bytes));

        // position的位置=2
        System.out.println(byteBuffer.position());
        // 标记 此时position为2
        byteBuffer.mark();
        // 再去获取值
        byteBuffer.get(bytes, 2, 2);
        System.out.println(new String(bytes));
        // position=4
        System.out.println(byteBuffer.position());
        // 恢复position标记
        byteBuffer.reset();
        // position=2
        System.out.println(byteBuffer.position());
    }

    @Test
    public void test3() {
        // 创建直接缓冲区
        ByteBuffer byteBuffer = ByteBuffer.allocateDirect(1024);
        // api是一样的
    }
}
